
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, roc_curve
from sklearn.preprocessing import StandardScaler

# 读取文件
excel_file = pd.ExcelFile('C:/Users/Administrator/Downloads/信用卡精准营销模型.xlsx')
df = excel_file.parse('Sheet1')

# 数据基本信息查看
print('数据基本信息：')
df.info()

# 查看数据集行数和列数
rows, columns = df.shape

if rows < 100 and columns < 20:
    print('数据全部内容信息：')
    print(df.to_csv(sep='\t', na_rep='nan'))
else:
    print('数据前几行内容信息：')
    print(df.head().to_csv(sep='\t', na_rep='nan'))

# 设置图片清晰度和中文字体
plt.rcParams['figure.dpi'] = 300
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC']
plt.rcParams['axes.unicode_minus'] = False

# 更全面的探索性数据分析
print("\n--- 描述性统计分析 ---")
print(df.describe().round(2))

# 相关性分析增强版
print("\n--- 相关性分析 ---")
correlation = df.corr()
print(correlation.round(4))

# 绘制相关性热力图
plt.figure(figsize=(10, 8))
mask = np.triu(np.ones_like(correlation, dtype=bool))
sns.heatmap(correlation, mask=mask, annot=True, fmt=".4f", cmap='coolwarm', square=True)
plt.title('特征相关性热力图')
plt.tight_layout()
plt.show()

# 分析各特征的分布情况
fig, axes = plt.subplots(2, 3, figsize=(15, 10))

sns.histplot(df['年龄'], bins=20, kde=True, ax=axes[0, 0])
axes[0, 0].set_title('年龄分布')

sns.histplot(df['月收入（元）'], bins=20, kde=True, ax=axes[0, 1])
axes[0, 1].set_title('月收入分布')

sns.histplot(df['月消费（元）'], bins=20, kde=True, ax=axes[0, 2])
axes[0, 2].set_title('月消费分布')

sns.countplot(x='性别', data=df, ax=axes[1, 0])
axes[1, 0].set_title('性别分布')

sns.histplot(df['月消费/月收入'], bins=20, kde=True, ax=axes[1, 1])
axes[1, 1].set_title('月消费/月收入分布')

sns.countplot(x='响应', data=df, ax=axes[1, 2])
axes[1, 2].set_title('响应分布')

plt.tight_layout()
plt.show()

# 绘制特征与响应变量的关系图
plt.figure(figsize=(14, 10))

plt.subplot(2, 2, 1)
sns.boxplot(x='响应', y='年龄', data=df)
plt.title('年龄与响应关系')

plt.subplot(2, 2, 2)
sns.boxplot(x='响应', y='月收入（元）', data=df)
plt.title('月收入与响应关系')

plt.subplot(2, 2, 3)
sns.boxplot(x='响应', y='月消费（元）', data=df)
plt.title('月消费与响应关系')

plt.subplot(2, 2, 4)
sns.boxplot(x='响应', y='月消费/月收入', data=df)
plt.title('消费收入比与响应关系')

plt.tight_layout()
plt.show()

# 准备特征和目标变量
X = df.drop('响应', axis=1)
y = df['响应']

# 标准化特征（对逻辑回归很重要）
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

# 构建逻辑回归模型
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = model.predict(X_test)
y_pred_proba = model.predict_proba(X_test)[:, 1]

# 模型评价
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
roc_auc = roc_auc_score(y_test, y_pred_proba)

print('\n--- 模型评价指标 ---')
print(f'准确率：{accuracy:.4f}')
print(f'精确率：{precision:.4f}')
print(f'召回率：{recall:.4f}')
print(f'F1分数：{f1:.4f}')
print(f'ROC-AUC分数：{roc_auc:.4f}')

# 绘制ROC曲线
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, label=f'ROC曲线 (AUC = {roc_auc:.4f})')
plt.plot([0, 1], [0, 1], 'k--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('假阳性率')
plt.ylabel('真阳性率')
plt.title('ROC曲线')
plt.legend(loc="lower right")
plt.show()

# 特征重要性分析
feature_importance = pd.DataFrame({
    '特征': X.columns,
    '系数': model.coef_[0],
    '绝对值系数': np.abs(model.coef_[0])
})

feature_importance = feature_importance.sort_values('绝对值系数', ascending=False)
print('\n--- 特征重要性排序 ---')
print(feature_importance)

# 绘制特征重要性条形图
plt.figure(figsize=(10, 6))
sns.barplot(x='绝对值系数', y='特征', data=feature_importance)
plt.title('特征重要性（逻辑回归系数绝对值）')
plt.tight_layout()
plt.show()

# 混淆矩阵可视化
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)

plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues")
plt.xlabel('预测值')
plt.ylabel('实际值')
plt.title('混淆矩阵')
plt.show()

# 绘制各特征与响应的相关性柱状图
correlation_with_response = df.corr()['响应'].drop('响应')
plt.figure(figsize=(8, 5))
correlation_with_response.plot(kind='bar')
plt.title('各特征与响应的相关性柱状图')
plt.xlabel('特征')
plt.ylabel('相关性')
plt.xticks(rotation=45)
plt.show()